package com.sandasai.service.impl;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;

import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sandasai.dao.AdminDao;
import com.sandasai.dao.BankcardDao;
import com.sandasai.dao.MarkDao;
import com.sandasai.dao.SettingDao;
import com.sandasai.dao.StudentDao;
import com.sandasai.dao.TeacherDao;
import com.sandasai.dao.UserDao;
import com.sandasai.dao.WorkDao;
import com.sandasai.dao.WorktypeDao;
import com.sandasai.domain.Mark;
import com.sandasai.domain.Setting;
import com.sandasai.domain.Student;
import com.sandasai.domain.Teacher;
import com.sandasai.domain.User;
import com.sandasai.domain.Work;
import com.sandasai.service.UserManager;
import com.sandasai.vo.UserBean;
@Service("userManager")
@Transactional
public class UserManagerImpl implements UserManager{
    @Resource
    private UserDao userDao;
    @Resource
    private StudentDao studentDao;
    @Resource
    private TeacherDao teacherDao;
    @Resource
    private AdminDao adminDao;
    @Resource
    private WorktypeDao worktypeDao;
    @Resource
    private WorkDao workDao;
    @Resource
    private MarkDao markDao;
    @Resource
    private SettingDao settingDao;
    @Resource
    private BankcardDao bankcardDao;
    @Resource
	private JavaMailSender javaMailSender;
    
    private static String systemEmail = "sandasai@163.com";
    /**
     * 该函数用来检查用户名是否被注册
     * @param username，需要检查的用户名
     * @return true:该用户名已经被注册，false:该用户名还没有被注册
     */
    @Override
    public boolean checkUsername(String username) {
        return userDao.findByUsername(username) != null;
    }
    /**
     * 该函数用来检查邮箱是否被注册
     * @param username，需要检查的邮箱
     * @return true:该用邮箱已经被注册，false:该邮箱还没有被注册
     */
    @Override
    public boolean checkEmail(String email) {
        return userDao.findByEmail(email) != null;
    }
    /**
     * 根据用户名或邮箱和密码，获取包含用户名和用户类型信息的UserBean
     * @param usernameOrEmail
     * @param password
     * @return 如果用户名或邮箱和密码匹配，则返回带有用户名和用户类型信息的UserBean，否则返回null
     */
    @Override
    public UserBean getUserBean(String usernameOrEmail, String password) {
    	User user = userDao.findByUsernameOrEmailAndPassword(usernameOrEmail, password);
    	if(user == null) {
    		return null;
    	}else {
    		 UserBean userBean = new UserBean();
             userBean.setUsername(user.getUsername());
             if(user.getStudent() != null) {
                 userBean.setUserType(UserBean.USER_TYPE_STUDENT);
             }else if(user.getTeacher() != null) {
                 userBean.setUserType(UserBean.USER_TYPE_TEACHER);
             }else if(user.getAdmin() != null){
                 userBean.setUserType(UserBean.USER_TYPE_ADMIN);
             }else {
                 return null;
             }
             return userBean;
    	}
    }
    @Override
    public boolean checkRegistration(UserBean userBean) {
        if(!checkUsername(userBean.getUsername()) && !checkEmail(userBean.getEmail()) 
        		&& !checkUsername(userBean.getEmail()) && !checkEmail(userBean.getUsername())) {
            User user = new User();
            user.setUsername(userBean.getUsername());
            user.setPassword(userBean.getPassword());
            user.setEmail(userBean.getEmail());
            user.setEmailVerified(false);
            Date date = new Date();
            Timestamp registrationDate = new Timestamp(date.getTime());
            user.setRegistrationDate(registrationDate);	
            Student student = new Student();
            student.setUser(user);
            user.setStudent(student);
            userDao.save(user);
            return true;
        }else {
            return false;
        }
    }
    @Override
    public boolean isWithinRegistrationTime() {
        Date startTimeOfRegistration = getStartTimeOfRegistration();
        Date endTimeOfRegistration = getEndTimeOfRegistration();
        if(startTimeOfRegistration == null || endTimeOfRegistration == null) {
            return false;
        }else {
            Date currentTime = new Date();
            if(!currentTime.after(startTimeOfRegistration) || !currentTime.before(endTimeOfRegistration)) {
                return false;
            }
            return true;
        }
    }
    @Override
    public Date getStartTimeOfRegistration() {
        List<Setting> settings = settingDao.findAll();
        if(settings.size() == 0) {
            return null;
        }
        return new Date(settings.get(settings.size() - 1).getStartTimeOfRegistration().getTime());
    }
    @Override
    public Date getEndTimeOfRegistration() {
        List<Setting> settings = settingDao.findAll();
        if(settings.size() == 0) {
            return null;
        }
        return new Date(settings.get(settings.size() - 1).getEndTimeOfRegistration().getTime());
    }
	@Override
	public boolean isAccessible(Integer userType, String username,
			String fileName) {
		User user = userDao.findByUsername(username);
		if(userType.equals(UserBean.USER_TYPE_STUDENT)) {
			Student student = user.getStudent();
			Work work = student.getWork();
			if(work == null) {
				return false;
			}else {
				if(!work.getFileName().equals(fileName)) {
					return false;
				}else {
					return true;
				}
			}
		}else if(userType.equals(UserBean.USER_TYPE_TEACHER)) {
			Teacher teacher = user.getTeacher();
			Set<Mark> marks =  teacher.getMarks();
			for(Mark mark : marks) {
				if(mark.getWork().getFileName().equals(fileName)) {
					return true;
				}
			}
			return false;
		}
		return true;
	}
	@Override
	public boolean sendActivationEmail(String username) {
		User user = userDao.findByUsername(username);
		user.setActiveCode(UUID.randomUUID().toString());
		String link = "http://localhost:8080/sandasai/active.action?activeCode=" + user.getActiveCode() + "&amp;username=" + username;
		try {
			sendMail(user.getEmail(), "Please Activate Your Account [sandasai]", link);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	@Override
	public void sendMail(String to, String subject, String htmlText)
			throws Exception {
		try {
			MimeMessage msg = javaMailSender.createMimeMessage();
			MimeMessageHelper msgHelper = new MimeMessageHelper(msg);
			
			msgHelper.setFrom(systemEmail);
			msgHelper.setTo(to);
			msgHelper.setSubject(subject);
			msgHelper.setText(htmlText, true);
			
			javaMailSender.send(msg);
		} catch (Exception e) {
			throw new Exception("Faild to send mail.", e);
		}
	}
	@Override
	public boolean activeAccount(String username, String activeCode) {
		User user = userDao.findByUsername(username);
		if(user.getActiveCode().equals(activeCode)) {
			user.setEmailVerified(true);
			return true;
		}else {
			return false;
		}
	}
}